#include "led.h"
#include "systick.h"

void LedInit(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(WS2812_RCC_PORT ,ENABLE);

	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = WS2812_PIN;
	GPIO_Init(WS2812_PORT, &GPIO_InitStructure);  

	GPIO_ResetBits(WS2812_PORT,WS2812_PIN);
	RGB_LED_Reset();
	TopLedColorSet(BLACK);
}

static void RGB_LED_Write0(void)
{
	RGB_LED_HIGH;
	//一个__nop()延时一个时钟周期，一个时钟周期约等于1/72000000，约13.9ns
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
	__nop();__nop();
	
	RGB_LED_LOW;
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
}

static void RGB_LED_Write1(void)
{
	RGB_LED_HIGH;
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
	__nop();__nop();
	
	RGB_LED_LOW;
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
	__nop();__nop();
	

}
 
static void RGB_LED_Reset(void)
{
	RGB_LED_LOW;
	delay_ms(1);
}
 
static void RGB_LED_Write_Byte(uint8_t byte)
{
	uint8_t i;
 
	for(i=0;i<8;i++)
		{
			if(byte&0x80)
				{
					RGB_LED_Write1();
			}
			else
				{
					RGB_LED_Write0();
			}
		byte <<= 1;
	}
}
 
static void RGB_LED_Write_24Bits(uint8_t green,uint8_t red,uint8_t blue)
{
	RGB_LED_Write_Byte(green);
	RGB_LED_Write_Byte(red);
	RGB_LED_Write_Byte(blue);
}
 
static void RGB_LED_Red(void)
{
	 uint8_t i;
	for(i=0;i<1;i++)
		{
			RGB_LED_Write_24Bits(0, 0x64, 0);
	}
}
 
static void RGB_LED_Green(void)
{
	uint8_t i;
 
	for(i=0;i<1;i++)
		{
			RGB_LED_Write_24Bits(0x64, 0, 0);
	}
}
 
static void RGB_LED_Blue(void)
{
	uint8_t i;
 
	for(i=0;i<1;i++)
		{
			RGB_LED_Write_24Bits(0, 0, 0x64);
	}
}


//LED灯颜色设置
void TopLedColorSet(const LedColor ledColor)
{
	static LedColor lastColor = BLACK;
	
	if(lastColor == ledColor){		//若设置的颜色与上次相同，则不往下执行
		return;
	} else {
		lastColor = ledColor;
	}
	
	switch(ledColor){
		case RED:
			RGB_LED_Red();//红
			break;
		case GREEN:
			RGB_LED_Green();//绿
			break;
		case BLUE:
			RGB_LED_Blue();//蓝
			break;
		case YELLOW:	//黄
			RGB_LED_Write_24Bits(0x32, 0x32, 0);
			break;
		case PURPLE:	//紫
			RGB_LED_Write_24Bits(0, 0x32, 0x32);
			break;
		case CYAN:	//青
			RGB_LED_Write_24Bits(0x32, 0, 0x32);
			break;
		case WHITE:	//白
			RGB_LED_Write_24Bits(0x32, 0x32, 0x32);
			break;
		default :
			RGB_LED_Write_24Bits(0, 0, 0);	//全灭
			break;
	}
}


//状态RGB灯闪烁设置,5hz
void RgbLedBlinkFast(LedColor ledColor)
{
	static uint8_t blinkCount = 0;
	
	if(blinkCount == 0){
		TopLedColorSet(ledColor);
	}
	else if(blinkCount == 5){
		TopLedColorSet(BLACK);
	}
	
	blinkCount++;
	if(blinkCount == 9){
		blinkCount = 0;
	}

}

//状态RGB灯闪烁设置,2hz
void RgbLedBlinkSlow(LedColor ledColor)
{
	static uint8_t blinkCount = 0;
	
	if(blinkCount == 0){
		TopLedColorSet(ledColor);
	}
	else if(blinkCount == 12){
		TopLedColorSet(BLACK);
	}
	
	blinkCount++;
	if(blinkCount == 24){
		blinkCount = 0;
	}

}

/*
@func: 设置状态指示灯闪烁
@param ledColor: 灯的颜色
@param frequency: 闪烁的频率
@param delayMs: 当前线程的延时时间
*/
void TopLedBlink(LedColor ledColor, uint8_t frequency, uint16_t delayMs)
{
	static uint16_t blinkCount = 0;
	uint16_t period = 0;

	period = 1000 / (delayMs * frequency * 2);
	if(blinkCount == 0){
		TopLedColorSet(ledColor);
	}
	else if(blinkCount == period){
		TopLedColorSet(BLACK);
	}
	
	blinkCount++;
	if(blinkCount == (2 * period)){
		blinkCount = 0;
	}
}
